# Copyright (C) 2003-2004, 2006, 2009 The Written Word, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# $Id$

import os

import depot
import pycurl

from depot.ftp import ftp
from misclib import urljoin

class sftp (ftp):
  """Remote package `Depot` over SFTP."""

  def _protocol_auth (self, c):
    """Handle SFTP specific authentication."""
    if self.auth.login:
      c.setopt (pycurl.USERPWD, self.auth.login + ':')
      c.setopt (pycurl.SSLKEYPASSWD, self.auth.passwd)

    # Handle ssh authentication:
    if self.auth.sftp_private_key_path:
      c.setopt (pycurl.SSH_PRIVATE_KEYFILE,
                self.auth.sftp_private_key_path)
      c.setopt (pycurl.SSH_PUBLIC_KEYFILE,
                self.auth.sftp_private_key_path + '.pub')

    if self.auth.sftp_known_hosts_path:
      c.setopt (pycurl.SSH_KNOWNHOSTS, self.auth.sftp_known_hosts_path)

  # set authentication for depot
  def set_auth (self, c):
    # check for ssh_known_hosts file and private key file
    if not self.auth.sftp_known_hosts_path:
      raise depot.DepotSftpKnownHostsFileNotSpecifiedError ('path \
to ssh_known_hosts file not specified. either specify it on the \
command-line with --sftp-known-hosts-path or with the \
sftp_known_hosts_path in the config file.')
    if not self.auth.sftp_private_key_path:
      raise depot.DepotSftpPrivateKeyFileNotSpecifiedError ('private \
key file not specified. either specify it on the command-line with \
--sftp-private-key-path or with the sftp_private_key_path variable \
in the config file.')
    if not os.path.exists (self.auth.sftp_known_hosts_path):
      raise depot.DepotSftpKnownHostsFileNotFoundError \
            ('unable to find ssh_known_hosts file "' +
             self.auth.sftp_known_hosts_path + '".')
    if not os.path.exists (self.auth.sftp_private_key_path):
      raise depot.DepotSftpPrivateKeyFileNotFoundError \
            ('unable to find private key file "' +
             self.auth.sftp_private_key_path + '".')

  def exists (self, filename):
    """Test whether `filename` is present at the remote host.

    :Parameters:
        `filename`: string
            Path to remote file relative to remote repository.

    :Return:
        - True unless remote file cannot be found.
    """

    # save full url in case of error
    _url = urljoin (self.pkg_url, filename)

    try:
      self._perform ({
        pycurl.URL: _url,
        pycurl.WRITEDATA: open ('/dev/null', 'wb'),  # discard headers
        pycurl.RANGE: '0-0',                         # fetch 1st byte only
        pycurl.NOPROGRESS: 1,
        pycurl.FAILONERROR: 1,
      })
    except depot.DepotFileNotFoundError:
      return False

    return True
